/** 
 * @addtogroup gbc_msg_17691
 * gbc_17691_codec
 * @brief        国六协议编解码，协议最底层的编解码接口
 * @par 示例
 * @code
   // 协议编码是将消息头和数据PDU部分组成国六协议数据，
   // 编码后不含标识符(0x23 0x23)和校验码，需要后续加入
   // 协议解码可以把收到原始报文进行解码，解码后得到消息头和PDU数据部分

   TGbc17691MsgHead msg_head;  ///< 存放解析后的消息头
   Int32 remove_size; ///< 解析后删除的缓存数据长度
   // 测试的需要解码的数据
   UInt8 buf[] = "23230130303030303030323030383231303931370101001C14090115372B000138393836303131373739353935303231323837343A"
   UInt8 data[256]; ///< data长度必须大于buf转换成二进制后的长度
   Int32 len = Ascii2Hex(data, temp);
   // 调用解码API
   int msg_len = Gbc17691Decode(data, len, &msg_head, &remove_size);
   if (msg_len > 0) ///< 解出消息长度大于0
   {
       ...
   }

   // 数据编码示例
   TGbc17691Mgr mgr; ///< 管理器对象
   UInt8 cmd = kGbc17691CmdLogin; ///< 消息命令字
   TGbc17691MgrCreate(&mgr, kGbc17691ProtocolSd, 1, kGbc17691ETypeNotEncrypt);
   ...///< 管理器属性赋值
   TGbc17691MgrCreateMsgHead(msg_mgr, cmd, &msg_head); ///< 创建消息头
   enc_len = Gbc17691Encode(&msg_head, buf, buf_size);
   ...
 * @endcode
 * @{
 */
/**
 * @file         gbc_17691_codec.h
 * @brief        国六协议底层编解码接口(API)
 * @note
 * @author       dengdeshou
 * @date         2020-08-05
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2020-08-05  <td>1.0                   <td>Dengdeshou      <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _SCC_PT17691_CODEC_H_
#define _SCC_PT17691_CODEC_H_

#include "ofc/ofc_object.h"

#define SCCF_17691_TAG_LEN 2
#define SCCF_17691_TAG 0x23
#define SCCF_17691_POSOF_LENTH 20
#define SCCF_17691_LENOF_VIN 17   ///< VIN码长度
#define SCCF_LENOF_ZZ_STREAM_ACK 7///< 郑州信息流应答包长度

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 错误码定义
 */
enum TGbc17691ErrorCodeEnumTag
{
    kGbc17691ErrorFail = 0,             ///< 编解码错误
    kGbc17691ErrorParamError = -1,      ///< 参数错误
    kGbc17691ErrorMemNotEnough = -2,    ///< 内存不足
    kGbc17691ErrorCrc = -3,             ///< 校验码不正确
};
typedef enum TGbc17691ErrorCodeEnumTag TGbc17691ErrorCodeEnum;

/**
 * 国六17691协议头
 */
typedef struct TGbc17691MsgHeadTag TGbc17691MsgHead;
struct TGbc17691MsgHeadTag
{
    Int8 cmd;               ///< 命令单元
    Int8 vin[SCCF_17691_LENOF_VIN];   ///< 车辆VIN码
    UInt8 soft_ver;         ///< 软件版本号
    UInt8 encrypt_type;     ///< 加密类型,参考TGbc17691EncryptTypeEnum
    UInt16 pdu_lenth;       ///< 数据部分长度
    UInt8 ack_result;       ///< 应答码，00正确，其他表示错误，此项为郑州协议中0xf0下行专用
    UInt16 ack_seq;         ///< 应答流水号，信息流上传对应的流水号，此项为郑州协议中0xf0下行专用
    void *pdu;              ///< 数据部分内容指针
};

/**
 * 国六协议解码
 * @param buf: 需要解码的数据缓冲区
 * @param buf_size: 数据缓冲区的大小
 * @param msg_head: 解码后解析出的消息头，内含消息内容地址
 * @param remove_size: 解码后需要移除的缓冲区大小
 * @return 解码后消息的长度,负数时为错误码,参照TGbc17691ErrorCodeEnum
 */
Int32 Gbc17691Decode(UInt8 *buf, UInt32 buf_size, TGbc17691MsgHead *msg_head, Int32 *remove_size);

/**
 * 国六协议编码
 * @param msg_head: 用于编码的消息头，内含消息内容地址
 * @param buf: 编码后存放的数据缓冲区
 * @param buf_size: 缓冲区的大小
 * @return 编码后获得的消息长度，负数时为错误码，参照TGbc17691ErrorCodeEnum
 */
Int32 Gbc17691Encode(TGbc17691MsgHead *msg_head, UInt8 *buf, UInt32 buf_size);
#ifdef __cplusplus
}
#endif

#endif
/**
 * @} 
 */
